import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Vector;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ScrollPaneLayout;
import javax.swing.table.DefaultTableModel;


public class ServerGUI extends JFrame{
	//jframe members - top panel
	private final JPanel topPanel;
	
	//jframe members - connections table
	private final JTable connectnsTab;
	private final JScrollPane connectnsTabPane;
	private final JPanel connectnsTabPanel;
		//members describing the content of the connection table
	private final String[] connectnsTabCols;
	private DefaultTableModel connectnsTabModel;
	
	//program-related info
	private boolean stopRequested = false;
	private boolean acceptNewConnections = true;
	
	public ServerGUI(){
		super("Temp Server Gui");
		this.setTitle("CloudCopter Server");
		
		//add the top icon
		Image icon;
		try {
			File imgIn = new File("icon48.png");
			icon = ImageIO.read(imgIn);
			this.setIconImage(icon);
		} catch (IOException e) { e.printStackTrace(); }

		//define the window layout
		BorderLayout borderLayout = new BorderLayout();
		this.setLayout(borderLayout);
		
		//define what happens when we turn off the server
		this.addWindowListener(new java.awt.event.WindowAdapter(){
			@Override
			public void windowClosing(java.awt.event.WindowEvent windowEv){
				//kill any running threads TODO
				setStop(true);
				//exit
				System.exit(0);
			}
		});
		
		//add a pause/restart button
		JButton pauseButton;

		//set up the connections table
		this.connectnsTabCols = new String[] { "Controller", "Vehicle" };
		this.connectnsTabModel = new DefaultTableModel(connectnsTabCols, 0);
		this.connectnsTab = new JTable(connectnsTabModel);

		this.connectnsTab.setRowSelectionAllowed(true);
		this.connectnsTab.setColumnSelectionAllowed(false);
		
		//add the JTable to a scrollable area
		this.connectnsTabPane = new JScrollPane(this.connectnsTab);
		//add the scrollable containing the JTable to the JPanel
		this.connectnsTabPanel = new JPanel();
		this.connectnsTabPanel.setLayout(new BorderLayout());
		this.connectnsTabPanel.add(this.connectnsTabPane, BorderLayout.NORTH);
		this.connectnsTabPanel.validate();
		
		
		
		//set up the top panel
		this.topPanel = new JPanel();
		
		//lay out the JPanels of the GUI
		this.add(this.connectnsTabPanel, BorderLayout.SOUTH);
		this.pack();
		this.setMinimumSize( this.getPreferredSize() ); //we can't shrink the window below its starting size
		
		this.setVisible(true);
	}
	
	//add a row which shows the details about a control session
	public void addControlSession(Vector<String> rowToAdd) {
		this.connectnsTabModel.addRow(rowToAdd);
	}
	
	//remove a row corresponding to a control session which has terminated
	public boolean removeControlSession(Vector<String> rowToAdd) {
		//start comparing the 0th element of the input vector to the 0th column of each row in the table
		boolean tgtFound = false;
		int tgt = 0;
		for(int i = 0; i < this.connectnsTabModel.getRowCount(); i++) {
			boolean rowMatches = true;
			int maxComparisons = Math.min(rowToAdd.size(), this.connectnsTabModel.getColumnCount());
			for(int j = 0; j < maxComparisons; j++) {
				if( !this.connectnsTabModel.getValueAt(i, j).toString().matches(rowToAdd.elementAt(j)) ) {
					rowMatches = false;
					break;
				}
			}
			if(rowMatches) {
				tgt = i;
				tgtFound = true;
				break;
			}
		}
		if(tgtFound) {
			this.connectnsTabModel.removeRow(tgt);
			return true;
		}
		return false;
	}
	
	public boolean getStop() {
		return this.setStop(false);
	}
	
	public boolean requestStop() {
		return this.setStop(true);
	}
	
	private synchronized boolean setStop(boolean newStopReqdVal) {
		this.stopRequested = newStopReqdVal;
		return this.stopRequested;
	}
	
	public synchronized boolean getOrSetAcceptConnect(boolean changeValue, boolean newConnAcceptVal) {
		if(changeValue) {
			this.acceptNewConnections = newConnAcceptVal;
		}
		return this.acceptNewConnections;
	}
}
